// Copyright Notice:
//			      on_screen_kb.js v1.0.1
//			Copyright@2008-2009 - OpenSiteMobile
//				All rights reserved
// ==========================================================================
//			http://www.opensitemobile.com
// ==========================================================================
// Contact Information:
//			Author: Dwight Vietzke
//			Email:  dwight_vietzke@yahoo.com

/*
	OpenSiteMobile on-screen keyboard w/dojo integration
*/

dojo.provide("msos.on_screen_kb");
dojo.require("msos.characters");
dojo.require("msos.common");
dojo.require("msos.input_events");
dojo.require("msos.input_select");
dojo.require("msos.selection");
dojo.require("dojo.dnd.Moveable");
dojo.require("dojo.i18n");


msos.on_screen_kb.create_tool = function(keyboard_container, keyboard_header, keyboard_close, keyboard_display, in_array) {

        // Get the language file to use as base
        dojo.requireLocalization('msos', 'keyboard', djConfig.locale);

        this.i18n		= dojo.i18n.getLocalization('msos', 'keyboard', djConfig.locale);
	this.container		= keyboard_container;
        this.header		= keyboard_header;
        this.close		= keyboard_close;
        this.display		= keyboard_display;
	this.created		= false;
        this.i18n_idx		= 0;    // set default (0 for english), ref. msos.characters.available
        this.tool_target	= null;
        this.tool_iframe	= null;
	this.suppressed_elements = new Array();

	this._vars = {
		debug :		"Keyboard Element Build:\n\n",
		flag_caps :	false,
		flag_shift :	false,
		flag_alt :	false,
                start_lang :    djConfig.locale,
		char_keys :	new Array(),
		ctrl_keys :	new Array(),
		not_avail :	new Array(2),
		key_position :	{top: 1, left: 1},
                adj_left :      0,
                adj_top :       0,
                image_url :     djConfig.msos_folder + '/images/',
		ie_element_suppression : ['select', 'object', 'applet'],

		fc :	"#000",
		bg :	"#FFF",
		bc :	"#777",
		ibc :	"#CCC",
		lsc :	"#FF99CC",
		lic :	"#DDD"
	}

	// Add drag functionality to the virtual keyboard
        new dojo.dnd.Moveable(keyboard_container);

	// Condition any text inputs for browser compatibility
	for(var j = 0; j < in_array.length; j++) {
		if (/textarea|text|password/i.test(in_array[j].type)) {
			var inp_val = in_array[j].value;
			in_array[j].value = dojo.trim(inp_val);
		}
	}

	var keyboard_obj = this;

	// --------------------------
	// Helper Function, textarea or text input only
	// --------------------------

        this.set_input_focus_end = function(target) {
                var sel_obj = new msos.input_select.text_ins_del(target);
                sel_obj.input_init_focus();
                // Force cursor to end of current text input
                sel_obj.input_set_cursor();
		// Set target so keyboard can insert text
		keyboard_obj.tool_target = target;
                msos.common.debug_write(sel_obj.debug);
        }

	// --------------------------
	// Keyboard Event Functions
	// --------------------------

	this.keyb_button_onmouseup = function() {
		// If not built, make it so...
		if (!keyboard_obj.created) {
                        msos.input_events.set_event(keyboard_obj, in_array);
			msos.common.set_popup_position(
				keyboard_obj.container,
				in_array[0],
				keyboard_obj._vars
			);
			generate_keyboard(keyboard_obj);
			keyboard_obj.display_kb_window();
			keyboard_obj.created = true;
			return true;
		}
		// Toggle display of keyboard
		if ((keyboard_obj.container.style.visibility == '')
		 || (keyboard_obj.container.style.visibility == 'visible'))
                        { keyboard_obj.hide_kb_window();	}
		else	{ keyboard_obj.display_kb_window();	}
                return true;
	}

	this.select_lang_onclick = function(evt) {
		evt.preventDefault();
		evt.stopPropagation();
		var in_el = evt.target;

		if (in_el.key_is_active) {
			// Increment language by 1
			++keyboard_obj.i18n_idx;

			// Go to next langauge or start over
			if (keyboard_obj.i18n_idx > (msos.characters.available.length - 1)) keyboard_obj.i18n_idx = 0;

			refresh_layout(keyboard_obj);
		}
		msos.common.event_debug(evt, "\nLanguage index -> " + keyboard_obj.i18n_idx );
	}

	this.process_key_onclick = function(evt) {
		evt.preventDefault();
		evt.stopPropagation();
		var in_el = evt.target;
		var kb_vars = keyboard_obj._vars;
		var temp_txt = '';

		var val = in_el.subst ? in_el.subst : in_el.innerHTML;

		if (in_el.key_is_active) {
			if((val == "Caps") || (val == "Shift") || (val == "Alt")) {
				var flag = 'flag_' + val.toLowerCase();
				kb_vars[flag] = kb_vars[flag] ? false : true;
				val = '';
			} else if(in_el.dead) {
				if (in_el.dead == kb_vars.not_avail[1]) {
					kb_vars.not_avail[0] = null;
					kb_vars.not_avail[1] = null;
				} else {
					kb_vars.not_avail[0] = val;
					kb_vars.not_avail[1] = in_el.dead;
				  }
				val = '';
			} else {
				if(kb_vars.not_avail[1]) {
					kb_vars.not_avail[0] = null;
					kb_vars.not_avail[1] = null;
				}
				kb_vars.flag_alt = false;
				kb_vars.flag_shift = false;
			  }
			refresh_layout(keyboard_obj);

			if (val && keyboard_obj.tool_target) {
                                // Check for std. text input fields...
                                if (/textarea|text|password/i.test(keyboard_obj.tool_target.type)) {
                                        var sel_obj = new msos.input_select.text_ins_del(keyboard_obj.tool_target);
                                        sel_obj.input_init_focus();
                                        switch(val) {
                                                case "BkSp":	sel_obj.input_del_character(false);	break;
                                                case "Del":	sel_obj.input_del_character(true);	break;
                                                case "Tab":	sel_obj.input_ins_character("\t");	break;
                                                case "LF":	sel_obj.input_ins_character("\n");	break;
                                                case "BR":	sel_obj.input_ins_character("<br />");	break;
                                                case "SP":	sel_obj.input_ins_character("&#160;");	break;
                                                case "Space":   sel_obj.input_ins_character(" ");	break;
                                                case "&lt;":    sel_obj.input_ins_character("<");	break;
                                                case "&gt;":    sel_obj.input_ins_character(">");	break;
                                                case "&amp;":   sel_obj.input_ins_character("&");	break;
                                                case "&quot;":  sel_obj.input_ins_character('"');	break;
                                                case " ":       break;
                                                case "&#160;":  break;
                                                default:	sel_obj.input_ins_character(val);
                                        }
                                        temp_txt = sel_obj.debug;
                                // Otherwise, check for an iframe
                                } else if (keyboard_obj.tool_iframe) {
                                        var ifr = keyboard_obj.tool_iframe;
                                        var win = ifr.contentWindow;
                                        var doc = win.document;
                                        switch(val) {
                                                case "BkSp":
                                                        msos.input_select.set_bksp_del_select(win, doc, ifr, true);
                                                        break;
                                                case "Del":
                                                        msos.input_select.set_bksp_del_select(win, doc, ifr, false);
                                                        break;
                                                case "Tab":
                                                        msos.input_select.edit_insert_html(win, doc, ifr, "\t");
                                                        break;
                                                case "LF":
                                                        msos.input_select.edit_insert_html(win, doc, ifr, "<br />");
                                                        break;
                                                case "BR":
                                                        msos.input_select.edit_insert_html(win, doc, ifr, "<br />");
                                                        break;
                                                case "SP":
                                                        msos.input_select.edit_insert_html(win, doc, ifr, "&#160;");
                                                        break;
                                                case "Space":
                                                        var space_val = " ";
                                                        if (dojo.isIE) space_val = "&#160;";
                                                        msos.input_select.edit_insert_html(win, doc, ifr, space_val);
                                                        break;
                                                case " ":
							break;
                                                case "&#160;":
							break;
                                                default:
                                                        msos.input_select.edit_insert_html(win, doc, ifr, val);
                                        }
					temp_txt = "\nIframe detected";
                                  }
			} else {
				console.debug('process_key_onclick -> Failed: ' + (val ? 'missing tool target!' : 'missing value!'));
			  }
		}
		if (djConfig.msos_debug) {
			var temp_act = in_el.key_is_active	? 'true' :	        'false';
			var temp_ded = in_el.dead		? in_el.dead :		'false';
			var temp_sub = in_el.subst		? in_el.subst :		'na';
			var temp_inn = in_el.innerHTML		? in_el.innerHTML :     'na';
			temp_txt = "\nProcess key:"
				+ "\nValue  -> " + val
				+ "\nSubst  -> " + temp_sub
				+ "\nInner  -> " + temp_inn
				+ "\nActive -> " + temp_act
				+ "\nDead   -> " + temp_ded
				+ temp_txt;
			msos.common.event_debug(evt, temp_txt);
		}
	}
}


// --------------------------
// Keyboard Display Functions
// --------------------------

msos.on_screen_kb.create_tool.prototype.hide_kb_window = function() {
	this.container.style.visibility = 'hidden';
	this.restore_ie_objects();
}

msos.on_screen_kb.create_tool.prototype.display_kb_window = function() {
	this.suppress_ie_objects();
	this.container.style.visibility = 'visible';
}

msos.on_screen_kb.create_tool.prototype.suppress_ie_objects = function() {
	// Suppress IE objects under present virtual keyboard position
	msos.common.set_suppress_ie_objects(
		this.container,
		this._vars.ie_element_suppression,
		this.suppressed_elements
	);
	for(i=0; i<this.suppressed_elements.length; i++) {
		this.suppressed_elements[i].style.visibility = 'hidden';
	}
}

msos.on_screen_kb.create_tool.prototype.restore_ie_objects = function() {
	for(i=0; i<this.suppressed_elements.length; i++) {
		this.suppressed_elements[i].style.visibility = "";
	}
	this.suppressed_elements = [];
}


// --------------------------
// Keyboard Generation Functions
// --------------------------

function generate_keyboard (kb_obj) {
        var kb_disp = kb_obj.display;
        var kb_vars = kb_obj._vars;

	var e = "&#160;";
	var i;

	// Build key function
	var setup_key = function(in_html, in_title, div_class) {
		var div_top	= String(kb_obj._vars.key_position.top)	 + 'px';
		var div_left	= String(kb_obj._vars.key_position.left) + 'px';
		if(djConfig.debugAtAllCost) {
			kb_obj._vars.debug +=  "Top  -> " + div_top + ", Left  -> " + div_left;
			kb_obj._vars.debug += "\nKey -> " + in_html + ", Class -> " + div_class + "\n";
		}
		var div_obj = document.createElement("div");
		div_obj.className = div_class;
		div_obj.innerHTML = in_html;
		div_obj.title = in_title;
		div_obj.style.top = div_top;
		div_obj.style.left = div_left;

		dojo.connect(div_obj, "onmousedown",	null, function () { div_obj.style.borderStyle = 'inset';  });
		dojo.connect(div_obj, "onmouseup",	null, function () { div_obj.style.borderStyle = 'outset'; });

		kb_obj.display.appendChild(div_obj);
		return div_obj;
	}

        // Set the starting language to display
        // Note: this.i18n_idx default (0 for english)
        for(var j = 0; j < msos.characters.available.length; j++) {
                if (kb_vars.start_lang == msos.characters.available[j][2]) {
                        kb_obj.i18n_idx = j;
                }
        }

	// Disable selection of some keyboard elements
	msos.selection.disableSelection(kb_obj.container);
	msos.selection.disableSelection(kb_obj.header);
        msos.selection.disableSelection(kb_obj.close);
        msos.selection.disableSelection(kb_obj.display);

	// Configure our header 'close' button...
	var button_config = {
		img_name :		'close_button.gif',
		img_url :		kb_vars.image_url,
		img_title :		kb_obj.i18n.close_title,
		img_alt :		kb_obj.i18n.close_alt,
		img_size :		'img_cls',
		img_but_id :		'img_close',
		button_mouseup :	kb_obj.keyb_button_onmouseup
	}

	// Generate our keyboard close button...
	var kb_close_obj = new msos.common.generate_img_button(kb_obj.close);
	
	// And generate the button...
	for (var val in button_config) { kb_close_obj[val] = button_config[val]; }
	kb_close_obj.img_button_append();

        // Add some info to 'header' element
        kb_obj.header.innerHTML = '<span title="' + kb_obj.i18n.kb_position + '" class="bold_text">.. :: :: :: ..</span>';

	// 1st row (numbers)
	for(i = 0; i < 13; i++) {
		var num_key;
		num_key =		setup_key(i,		'', 'std_kb_cell');
		kb_vars.key_position.left += num_key.offsetWidth + 1;
		kb_vars.char_keys[i] = num_key;
	}

	kb_vars.ctrl_keys["backsp"] =	setup_key("BkSp",	kb_obj.i18n.backspace, 'bk_space_cell');
	kb_vars.key_position.top  = kb_vars.char_keys[0].offsetHeight + 2;
	kb_vars.key_position.left = 1;

	// 2nd row (alphabet)
	kb_vars.ctrl_keys["tab"] =	setup_key("Tab",	kb_obj.i18n.tab + " - \\t", 'tab_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["tab"].offsetWidth + 1;

	for(i; i < 26; i++) {
		var alph_key;
		alph_key =		setup_key(i,		'', 'std_kb_cell');
		kb_vars.key_position.left += alph_key.offsetWidth + 1;
		kb_vars.char_keys[i] = alph_key;
	}

	kb_vars.ctrl_keys["et"] =	setup_key(e,		kb_obj.i18n.linefeed + " - \\n", 'lf_top_cell');
	kb_vars.ctrl_keys["et"].subst = "LF";

	kb_vars.key_position.top  = kb_vars.char_keys[0].offsetHeight + kb_vars.ctrl_keys["tab"].offsetHeight + 3;
	kb_vars.key_position.left = 1;

	// Home row:
	kb_vars.ctrl_keys["caps"] =	setup_key("Caps",	kb_obj.i18n.caps_lock, 'caps_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["caps"].offsetWidth + 1;

	for(i; i < 38; i++) {
		var alph_2_key =	setup_key(i,		'', 'std_kb_cell');
		kb_vars.key_position.left += alph_2_key.offsetWidth + 1;
		kb_vars.char_keys[i] = alph_2_key;
	}

	kb_vars.ctrl_keys["e"] =	setup_key("LF",		kb_obj.i18n.linefeed + " - \\n", 'enter_cell');
	kb_vars.key_position.top  = kb_vars.char_keys[0].offsetHeight + kb_vars.ctrl_keys["tab"].offsetHeight + kb_vars.ctrl_keys["caps"].offsetHeight + 4;
	kb_vars.key_position.left = 1;

	kb_vars.ctrl_keys["sh"] =	setup_key("Shift",	kb_obj.i18n.shift, 'shift_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["sh"].offsetWidth + 1;

	for(i; i < 48; i++) {
		var alph_3_key =	setup_key(i,		'', 'std_kb_cell');
		kb_vars.key_position.left += alph_3_key.offsetWidth + 1;
		kb_vars.char_keys[i] = alph_3_key;
	}

	kb_vars.ctrl_keys["sr"] =	setup_key("Shift",	kb_obj.i18n.shift, 'shift_cell');
	kb_vars.key_position.top  = kb_vars.char_keys[0].offsetHeight + kb_vars.ctrl_keys["tab"].offsetHeight + kb_vars.ctrl_keys["caps"].offsetHeight + kb_vars.ctrl_keys["sh"].offsetHeight + 5;
	kb_vars.key_position.left = 1;

	// Language selector:
	kb_vars.ctrl_keys["lang"] =	setup_key(e,		'', 'bottom_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["lang"].offsetWidth + 1;

	kb_vars.ctrl_keys["sp"] =	setup_key("SP",		kb_obj.i18n.html + " &#160;", 'bottom_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["sp"].offsetWidth + 1;

	kb_vars.ctrl_keys["res_2"] =	setup_key(e,		'', 'bottom_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["res_2"].offsetWidth + 1;

	kb_vars.ctrl_keys["space"] =	setup_key('Space',	kb_obj.i18n.space, 'space_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["space"].offsetWidth + 1;

	kb_vars.ctrl_keys["del"] =	setup_key('Del',	kb_obj.i18n.del_key, 'bottom_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["del"].offsetWidth + 1;

	kb_vars.ctrl_keys["altgr"] =	setup_key("Alt",	kb_obj.i18n.alt, 'bottom_cell');
	kb_vars.key_position.left += kb_vars.ctrl_keys["altgr"].offsetWidth + 1;

	kb_vars.ctrl_keys["br"] =	setup_key("BR",		kb_obj.i18n.html + " <br />", 'bottom_cell');

	// Add event functions to our newly generated keys
	for(var j = 0; j < kb_vars.char_keys.length; j++) {
		var key = kb_vars.char_keys[j];
		key.unselectable = "on";
		dojo.connect(key, 'onclick', null, kb_obj.process_key_onclick);
	}
	// Add event functions to our newly generated control keys
	for(var k in kb_vars.ctrl_keys) {
		var key = kb_vars.ctrl_keys[k];
		key.unselectable = "on";
		if (k == "lang")	dojo.connect(key, 'onclick', null, kb_obj.select_lang_onclick);
		else			dojo.connect(key, 'onclick', null, kb_obj.process_key_onclick);
	}

	// Set applicable keys active (first time)
	refresh_layout(kb_obj);

        if (djConfig.debugAtAllCost) alert(kb_vars.debug);
}


function refresh_layout(vkb) {

	var set_key_state = function(key, onoff, textcolor, bordercolor, bgcolor, fontweight) {
		if(!key) return false;
		if(key.style) {
			if(textcolor)	key.style.color = textcolor;
			if(bordercolor) key.style.borderColor = bordercolor;
			if(bgcolor)	key.style.backgroundColor = bgcolor;
			if(fontweight)	key.style.fontWeight = fontweight;
		}
		key.key_is_active = onoff;
                return true;
	}

	var layout_name = msos.characters.available[vkb.i18n_idx][0].toLowerCase();

	var arr_type = vkb._vars.flag_alt ? (vkb._vars.flag_shift ? "alt_gr_shift" : "alt_gr") : (vkb._vars.flag_shift ? "shift" : (vkb._vars.flag_caps ? "caps" : "normal"));

	var nkeys = vkb._vars.char_keys.length;

	var lang_caps	= layout_name + '_caps';
	var lang_shift	= layout_name + '_shift';
	var lang_alt_gr	= layout_name + '_alt_gr';
	var lang_alt_gr_shift = layout_name + '_alt_gr_shift';

	var caps	= vkb._vars.ctrl_keys["caps"],	shift	= vkb._vars.ctrl_keys["sh"],	shift_r	= vkb._vars.ctrl_keys["sr"];
	var alt_gr	= vkb._vars.ctrl_keys["altgr"],	space	= vkb._vars.ctrl_keys["space"],	lang	= vkb._vars.ctrl_keys["lang"];
	var enter_t	= vkb._vars.ctrl_keys["et"],	enter_c	= vkb._vars.ctrl_keys["e"];
	var html_sp	= vkb._vars.ctrl_keys["sp"],	html_br	= vkb._vars.ctrl_keys["br"];

	if(msos.characters.groups[lang_shift] && (msos.characters.groups[lang_shift].length == nkeys)) {
		set_key_state(shift,	true,	vkb._vars.fc,  vkb._vars.bc,  vkb._vars.flag_shift ? vkb._vars.lic : vkb._vars.bg);
		set_key_state(shift_r,	true,	vkb._vars.fc,  vkb._vars.bc,  vkb._vars.flag_shift ? vkb._vars.lic : vkb._vars.bg);
	} else {
		set_key_state(shift,	false,	vkb._vars.ibc, vkb._vars.ibc, vkb._vars.bg);
		set_key_state(shift_r,	false,	vkb._vars.ibc, vkb._vars.ibc, vkb._vars.bg);

		if(arr_type == "shift") {
			arr_type = "normal";
			vkb._vars.flag_shift = false;
		}
	}

	if(msos.characters.groups[lang_alt_gr] && (msos.characters.groups[lang_alt_gr].length == nkeys)) {
				set_key_state(alt_gr,	true,  vkb._vars.fc,  vkb._vars.bc, vkb._vars.flag_alt ? vkb._vars.lic : vkb._vars.bg);

		if(vkb._vars.flag_alt) {
			if(msos.characters.groups[lang_alt_gr_shift] && (msos.characters.groups[lang_alt_gr_shift].length == nkeys)) {
				set_key_state(shift,	true,  vkb._vars.fc,  vkb._vars.bc, "");
				set_key_state(shift_r,	true,  vkb._vars.fc,  vkb._vars.bc, "");
			} else {
				set_key_state(shift,	false, vkb._vars.ibc, vkb._vars.ibc, vkb._vars.bg);
				set_key_state(shift_r,	false, vkb._vars.ibc, vkb._vars.ibc, vkb._vars.bg);

				arr_type = "alt_gr";
				vkb._vars.flag_shift = false;
			}
		}
	} else {
		set_key_state(alt_gr, false, vkb._vars.ibc, vkb._vars.ibc, vkb._vars.bg);

		if(arr_type == "alt_gr") {
			arr_type = "normal";
			vkb._vars.flag_alt = false;
		} else if(arr_type == "alt_gr_shift") {
			arr_type = "normal";
			vkb._vars.flag_alt = false, vkb._vars.flag_shift = false;

			shift.style.backgroundColor = vkb._vars.bg, shift_r.style.backgroundColor = vkb._vars.bg;
		}
	}

	if(msos.characters.groups[lang_caps] && (msos.characters.groups[lang_caps].length == nkeys) && !vkb._vars.flag_alt) {
		set_key_state(caps, true,	vkb._vars.fc,	vkb._vars.bc,	vkb._vars.flag_caps ? vkb._vars.lic : vkb._vars.bg);
	} else {
		set_key_state(caps, false,	vkb._vars.ibc,	vkb._vars.ibc,	vkb._vars.bg);

		vkb._vars.flag_caps = false;
		if(arr_type == "caps") arr_type = "normal";
	  }

	for(var i = 0; i < nkeys; i++) {
		var key = vkb._vars.char_keys[i];
		var key_val = '';
		if(vkb._vars.flag_shift && vkb._vars.flag_caps) {
			var key_nrm = msos.characters.groups[layout_name + "_normal"][i];
			var key_cps = msos.characters.groups[layout_name + "_caps"][i];
		 	var key_shf = msos.characters.groups[layout_name + "_shift"][i];
			if((key_cps == key_shf) && (key_nrm != key_cps)) {
                                key_val = key_nrm || '';
                        }
		} else {
			key_val = msos.characters.groups[layout_name + "_" + arr_type][i] || '';
		  }

		if(String(typeof(key_val)).toLowerCase() == "object") {
                        msos.common.xml_innerhtml(key, key_val[0]);
                        key.dead = key_val[1];
			set_key_state(key, true, "#F00", vkb._vars.bc, (vkb._vars.not_avail[0] == key_val[0] ? vkb._vars.lic : vkb._vars.bg));
		} else {
			key.dead = null;
			var block = false
			var dead = vkb._vars.not_avail[1] || null;

			if(key_val != "") {
				if(dead) {
					var j;
					dead = dead.toLowerCase();
					var diac_array = msos.characters.diacritic[dead] || null;
					for(j = 0; j < diac_array.length; j++) {
						if(diac_array && (diac_array[j][0] == key_val)) {
							key_val = diac_array[j][1];
							break;
						}
					}
					if(j == diac_array.length) block = true;
				}
                                msos.common.xml_innerhtml(key, key_val);
                                
				if(block)		set_key_state(key, false,	vkb._vars.ibc,	vkb._vars.ibc,	vkb._vars.bg,     'normal');
				else			set_key_state(key, true,	vkb._vars.fc,	vkb._vars.bc,	vkb._vars.bg,     'bold');
			} else {
                                msos.common.xml_innerhtml(key, "&#160;");
				set_key_state(key, false, vkb._vars.ibc, vkb._vars.ibc, vkb._vars.bg);
			}
		}
	}

	for(var k in vkb._vars.ctrl_keys) {
		var key = vkb._vars.ctrl_keys[k];

		switch(key) {
			case caps:
			case shift:
			case shift_r:
			case alt_gr:
			break;

			case space:
			if (vkb._vars.not_avail[1])	msos.common.xml_innerhtml(space, vkb._vars.not_avail[0]);
			else				space.innerHTML = "Space";
							set_key_state(key, true,	vkb._vars.fc,	vkb._vars.bc,	"");
			break;

			case lang:
			if (vkb._vars.not_avail[1])	set_key_state(key, false,	vkb._vars.ibc,	vkb._vars.ibc,	vkb._vars.bg );
			else				set_key_state(key, true,	vkb._vars.fc,	vkb._vars.bc,	vkb._vars.lsc);
			break;

			default:
			if(vkb._vars.not_avail[1])	set_key_state(key, false,	vkb._vars.ibc,	vkb._vars.ibc,	"");
			else				set_key_state(key, true,	vkb._vars.fc,	vkb._vars.bc,	"");
		}
	}

        lang.innerHTML = msos.characters.available[vkb.i18n_idx][0];
	lang.title     = msos.characters.available[vkb.i18n_idx][1];
}